package com.lcf.system.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.lcf.framework.exception.SysException;
import com.lcf.framework.utils.UserUtils;
import com.lcf.system.dao.RuleUserDao;
import com.lcf.system.entity.RoleDetail;
import com.lcf.system.entity.RuleUser;
import com.lcf.system.entity.SysTenantRule;
import com.lcf.system.enums.RuleStatusEnum;
import com.lcf.system.service.RuleUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;

/**
 * 规则报名表(RuleUser)表服务实现类
 *
 * @author lcf
 * @since 2025-05-03 11:45:10
 */
@Service("ruleUserService")
public class RuleUserServiceImpl extends ServiceImpl<RuleUserDao, RuleUser> implements RuleUserService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean signUp(long ruleId) {
        SysTenantRule tenantRule = Db.lambdaQuery(SysTenantRule.class).eq(SysTenantRule::getId, ruleId).one();
        if (tenantRule == null) {
            throw new SysException("活动不存在");
        }

        if (Objects.equals(tenantRule.getStatus(), RuleStatusEnum.WAIT_START.getCode())) {
            throw new SysException("活动未开始");
        }
        if (Objects.equals(tenantRule.getStatus(), RuleStatusEnum.END.getCode())) {
            throw new SysException("活动已结束");
        }
        if (Objects.equals(tenantRule.getIsOrder(), 1)) {
            throw new SysException("活动已结束");
        }

        long userId = UserUtils.getUserId();
        boolean exists = Db.lambdaQuery(RuleUser.class).eq(RuleUser::getRuleId, ruleId).eq(RuleUser::getUserId, userId).exists();
        if (exists) {
            throw new SysException("请勿重复报名");
        }

        new RuleUser(ruleId, userId, tenantRule.getGoodsId(), tenantRule.getGoodsNum()).insert();

        Long count = Db.lambdaQuery(RuleUser.class).eq(RuleUser::getRuleId, ruleId).count();

        List<RoleDetail> list = Db.lambdaQuery(RoleDetail.class).eq(RoleDetail::getRuleId, ruleId).list();
        RoleDetail detail = list.stream().filter(x -> x.getPeopleNum() <  count)
                .max(Comparator.comparing(RoleDetail::getPeopleNum)).orElse(null);

        if (detail == null) {
            return true;
        }

        Db.lambdaUpdate(SysTenantRule.class).eq(SysTenantRule::getId, ruleId).set(SysTenantRule::getDetailId, detail.getId()).update();

        return true;
    }
}

